/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/


#include "stdafx.h"
#include "Bullet刚体.h"


#define USE_MOTIONSTATE 1


#include <BulletDynamics\Character\btKinematicCharacterController.h>









S_Bullet静态碰撞::S_Bullet静态碰撞(S_物理几何体& geom, S_物理材质& 材质, uint32 key) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理体类型::E_物理体_静态;

	
	btCollisionShape* m_Shape = 0;

	switch (geom.m_Type) {
		case E_物理碰撞几何类型::E_碰撞几何_平面:
		{
			auto* g = dynamic_cast<S_Bulle平面*>(&geom);
			m_Shape = g->m_Shape;
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_方体:
		{
			//auto* g = new S_Bullet长方体几何体({ 80.f, 1.0f, 80.0f });
			auto* g = dynamic_cast<S_Bullet长方体几何体*>(&geom);
			m_Shape = g->m_Shape;
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_凸壳:
		{
			auto* g = dynamic_cast<S_Bullet凸包几何体*>(&geom);
			m_Shape = g->m_Shape;
		}
		break;


		case E_物理碰撞几何类型::E_碰撞几何_网格:
		{
			auto* g = dynamic_cast<S_Bullet网格几何体*>(&geom);
			m_Shape = g->m_Shape;
		}
		break;

		default:
			return;
	}
	btAssert((!m_Shape || m_Shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
	//m_Shape = new btBoxShape(btVector3(btScalar(100), btScalar(1), btScalar(100.0)));
	m_Shape->setMargin(0.01);

	btVector3 localInertia(0, 0, 0);

	btTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0, 0, 0));

	//m_Shape->calculateLocalInertia(重量, localInertia);
	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
	btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
	btRigidBody::btRigidBodyConstructionInfo cInfo(0, myMotionState, m_Shape, localInertia);
	m_Body = new btRigidBody(cInfo);
	
	//禁止休眠
	//m_Body = new btRigidBody(0.0f, 0, m_Shape, localInertia);
	//m_Body->setWorldTransform(groundTransform);
	m_Body->forceActivationState(DISABLE_DEACTIVATION);
	//m_Body->setCollisionFlags(btCollisionObject::CollisionFlags::CF_STATIC_OBJECT);
	//m_Body->forceActivationState(ACTIVE_TAG);
	//m_Body->activate(true);
	m_Body->setFriction(0.7);
	//m_Body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
	m_Body->setRestitution(0.5);
	m_Body->setDamping(0.0, 0);
}

S_Bullet静态碰撞::~S_Bullet静态碰撞() {

}

void S_Bullet静态碰撞::f_setLocRot(const vec3& loc, const vec3& r) {
	vec4 q = f_graph_欧拉角转四元数(r);

	btTransform sphereTrans;
	sphereTrans.setIdentity();
	sphereTrans.setOrigin(btVector3(loc.x, loc.y, loc.z));
	sphereTrans.setRotation({ q.x, q.y, q.z, q.w });
	m_Body->setWorldTransform(sphereTrans);
}

void S_Bullet静态碰撞::f_setPos(const vec3& loc) {
	btTransform sphereTrans;
	sphereTrans.setIdentity();
	sphereTrans.setOrigin(btVector3(loc.x, loc.y, loc.z));
	m_Body->setWorldTransform(sphereTrans);
}

void S_Bullet静态碰撞::f_setRot(const vec3& r) {
	m_Body->setAngularFactor({ r.x, r.y, r.z });
}

void S_Bullet静态碰撞::f_setVel(const vec3& l) {
	m_Body->setAngularVelocity({ 0.0,0.0,0.0 });
	m_Body->setLinearVelocity({ l.x, l.y, l.z });
}

vec3 S_Bullet静态碰撞::f_getLocation()
{
	return vec3();
}
















S_Bullet刚体::S_Bullet刚体(S_物理几何体& geom, S_物理材质* 材质, uint32 key) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理体类型::E_物理体_刚体;
	/// Create Dynamic Objects
	btTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0, 0, 0));
	//startTransform.setRotation(btQuaternion(btVector3(1, 1, 1), SIMD_PI / 10.));
	//btScalar mass(1.f);
	//bool isDynamic = (mass != 0.f);
	btCollisionShape* m_Shape = 0;
	float32 重量 = 1.0;


	switch (geom.m_Type) {
		case E_物理碰撞几何类型::E_碰撞几何_凸壳: {
			auto* g = dynamic_cast<S_Bullet凸包几何体*>(&geom);
			m_Shape = g->m_Shape;
			重量 = g->m_重量;
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_方体: {
			auto* g = dynamic_cast<S_Bullet长方体几何体*>(&geom);
			//auto* g = new S_Bullet长方体几何体({ 1.f, 1.0f, 1.0f });
			m_Shape = g->m_Shape;
			重量 = g->m_重量;
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_球体: {
			auto* g = dynamic_cast<S_Bullet球体几何体*>(&geom);
			//auto* g = new S_Bullet长方体几何体({ 1.f, 1.0f, 1.0f });
			m_Shape = g->m_Shape;
			重量 = g->m_重量;
		}
		break;

		case E_物理碰撞几何类型::E_碰撞几何_网格: {
			auto* g = dynamic_cast<S_Bullet网格几何体*>(&geom);
			//auto* g = new S_Bullet长方体几何体({ 1.f, 1.0f, 1.0f });
			m_Shape = g->m_Shape;
			重量 = g->m_重量;
		}
		break;

	default:
		return;
	}

	m_Shape->setMargin(0.01);
	//m_Shape = new btBoxShape(btVector3(btScalar(1), btScalar(1), btScalar(1.0)));
	btVector3 localInertia(0, 0, 0);
	m_Shape->calculateLocalInertia(1.0, localInertia);
	//m_Shape->setUserPointer();
	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects


#ifdef USE_MOTIONSTATE
	btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
	btRigidBody::btRigidBodyConstructionInfo cInfo(重量, myMotionState, m_Shape, localInertia);

	m_bt刚体 = new btRigidBody(cInfo);
	//body->setContactProcessingThreshold(m_defaultContactProcessingThreshold);

#else
	btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia);
	body->setWorldTransform(startTransform);
#endif  //
	//m_刚体->setUserIndex(key);
	//m_dynamicsWorld->addRigidBody(body);
	//m_刚体->setActivationState(ACTIVE_TAG);
	//m_刚体->setRollingFriction()
	//auto a = m_刚体->getContactStiffness();
	//禁止休眠
	//m_刚体->forceActivationState(DISABLE_DEACTIVATION);
	//m_刚体->setFriction(0.05f);
	//m_刚体->forceActivationState(ACTIVE_TAG);
	//m_刚体->setContactStiffnessAndDamping(0.1, 0.1);
	//m_刚体->setRestitution(0.9);
	//m_刚体->setDamping(0.001, 0.001);
	
}


S_Bullet刚体::~S_Bullet刚体() {
	/*int graphicsUid = body->getUserIndex();
	m_guiHelper->removeGraphicsInstance(graphicsUid);

	m_dynamicsWorld->removeRigidBody(body);
	btMotionState* ms = body->getMotionState();
	delete body;
	delete ms;*/
}

void S_Bullet刚体::f_setLocRot(const vec3& loc, const vec3& r) {
	vec4 q = f_graph_欧拉角转四元数(r);

	btTransform sphereTrans;
	sphereTrans.setIdentity();
	sphereTrans.setOrigin(btVector3(loc.x, loc.y, loc.z));
	sphereTrans.setRotation({ q.x, q.y, q.z, q.w });
	m_bt刚体->setWorldTransform(sphereTrans);
}

void S_Bullet刚体::f_setPos(const vec3& loc) {
	btTransform sphereTrans;
	sphereTrans.setIdentity();
	sphereTrans.setOrigin(btVector3(loc.x, loc.y, loc.z));
	m_bt刚体->setWorldTransform(sphereTrans);
}

void S_Bullet刚体::f_setRot(const vec3& r) {
	m_bt刚体->setAngularFactor({ r.x, r.y, r.z });
}

void S_Bullet刚体::f_setVel(const vec3& l) {
	m_bt刚体->setAngularVelocity({ 0.0,0.0,0.0 });
	m_bt刚体->setLinearVelocity({l.x, l.y, l.z});
}

vec3 S_Bullet刚体::f_getLocation() {
	return vec3();
}

vec3 S_Bullet刚体::f_getLoc() {
	auto loc = m_bt刚体->getCenterOfMassTransform().getOrigin();
	return { loc.x(), loc.y(), loc.z() };
}

void S_Bullet刚体::f_施加力(const vec3& 力) {
	//m_刚体->applyCentralForce({ 力.x, 力.y, 力.z });
	m_bt刚体->applyCentralImpulse({ 力.x, 力.y, 力.z });
}






















S_Bullet控制::S_Bullet控制(S_物理几何体& geom, S_物理材质& 材质, uint32 key) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理体类型::E_物理体_控制;


	btCollisionShape* m_Shape = 0;

	switch (geom.m_Type) {
	case E_物理碰撞几何类型::E_碰撞几何_平面:
	{
		auto* g = dynamic_cast<S_Bulle平面*>(&geom);
		m_Shape = g->m_Shape;
	}
	break;

	case E_物理碰撞几何类型::E_碰撞几何_方体:
	{
		//auto* g = new S_Bullet长方体几何体({ 80.f, 1.0f, 80.0f });
		auto* g = dynamic_cast<S_Bullet长方体几何体*>(&geom);
		m_Shape = g->m_Shape;
	}
	break;

	case E_物理碰撞几何类型::E_碰撞几何_凸壳:
	{
		auto* g = dynamic_cast<S_Bullet凸包几何体*>(&geom);
		m_Shape = g->m_Shape;
	}
	break;


	case E_物理碰撞几何类型::E_碰撞几何_网格:
	{
		auto* g = dynamic_cast<S_Bullet网格几何体*>(&geom);
		m_Shape = g->m_Shape;
	}
	break;

	default:
		return;
	}
	btAssert((!m_Shape || m_Shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
	//m_Shape = new btBoxShape(btVector3(btScalar(100), btScalar(1), btScalar(100.0)));
	m_Shape->setMargin(0.01);

	btVector3 localInertia(0, 0, 0);

	btTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0, 0, 0));

	//m_Shape->calculateLocalInertia(重量, localInertia);
	//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
	btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
	btRigidBody::btRigidBodyConstructionInfo cInfo(1.0, myMotionState, m_Shape, localInertia);
	m_Body = new btRigidBody(cInfo);

	//btKinematicCharacterController()
	
	m_Body->setFriction(0.5);
	auto a = m_Body->getCollisionFlags();
	//m_Body->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
	m_Body->setCollisionFlags(m_Body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
	m_Body->setDamping(0.00001, 0.00000000001);
	m_Body->setRestitution(0.8);
	//m_Body->setActivationState(DISABLE_DEACTIVATION);
	//m_Body->setActivationState(DISABLE_SIMULATION);
	//m_Body->forceActivationState(DISABLE_DEACTIVATION);

}

S_Bullet控制::~S_Bullet控制() {

}

void S_Bullet控制::f_setLocRot(const vec3& loc, const vec3& r) {
	vec4 q = f_graph_欧拉角转四元数(r);

	btTransform sphereTrans;
	sphereTrans.setIdentity();
	sphereTrans.setOrigin(btVector3(loc.x, loc.y, loc.z));
	sphereTrans.setRotation({ q.x, q.y, q.z, q.w });
	m_Body->setWorldTransform(sphereTrans);
}

void S_Bullet控制::f_setPos(const vec3& loc) {
	btTransform sphereTrans;
	sphereTrans.setIdentity();
	sphereTrans.setOrigin(btVector3(loc.x, loc.y, loc.z));
	//m_Body->setWorldTransform(sphereTrans);
	//m_Body->setInterpolationWorldTransform(sphereTrans);
	m_Body->getMotionState()->setWorldTransform(sphereTrans);
}

void S_Bullet控制::f_setRot(const vec3& r) {
	m_Body->setAngularFactor({ r.x, r.y, r.z });
}

void S_Bullet控制::f_setVel(const vec3& l) {
	m_Body->setAngularVelocity({ 0.0,0.0,0.0 });
	m_Body->setLinearVelocity({ l.x, l.y, l.z });
}

vec3 S_Bullet控制::f_getLocation() {
	return vec3();
}

vec3 S_Bullet控制::f_getLoc() {
	auto loc = m_Body->getCenterOfMassTransform().getOrigin();
	return { loc.x(), loc.y(), loc.z() };
}








